<!-- 需求：1.改时间和信息一个弹窗，时间条只改开始时间 时间间隔不变 ，2.改完时间如果出现最大最小值 时间条要改变，3.绿点要加入弹窗，4.echart需要动画， -->

<template>
  <div>
    <div style="margin-bottom: 30px;">
      自定义时间:
      <el-time-select
        v-model="startTime"
        placeholder="起始时间"
        :picker-options="{
          start: '00:00',
          step: '01:00',
          end: '23:59',
        }"
        @change="changeEndTime"
      />
      <el-time-select
        v-model="endTime"
        placeholder="结束时间"
        :picker-options="{
          start: '00:00',
          step: '01:00',
          end: '23:59',
        }"
        @change="changeEndTime"
      />
      <el-select v-model="timeInterval" placeholder="请选择" @change="changeEndTime">
        <el-option
          v-for="item in timeIntervalOptions"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>
      <span>{{ startTime }}-{{ endTime }}</span>
      <span>分钟数：{{ totalMin }}@@@@{{ perMin }}</span>
    </div>
    <div class="slide-ruler">
      <div v-for="time of timeList" :key="time" class="scale">{{ time }}</div>
    </div>
    <draggable
      v-model="schedulesList"
      class="row sortable-list"
      animation="300"
      handle=".mover"
      @end="end"
    >

      <div
        v-for="(row,index) in schedulesList"
        :key="row.index"
        class="sortable"
      >
        <span class="mover">+</span>
        <span>{{ index+1 }}</span>
        <div class="slide-list">
          <div class="slide-ruler-item">
            <div v-for="time of timeList" :key="time" class="scale-item" />
          </div>
          <div ref="slideBox" class="slide-box">
            <draggable
              :list="row.items"
              :group="{ name: 'row' }"
              class="row-item"
              handle=".mover-item"
              @start="start($event,schedulesList)"
              @end="end(schedulesList)"
            >
              <div
                v-for="(item, key) of row.items"
                :key="item.id"
                ref="slideBoxItem"
                class="slide-box-item"
                :style="`width: ${item.width}%; left: ${item.left}%; background: ${itemBGcolor[ key % 2 ]}`"
                @click.prevent="timeItemBlock(row.fid, key, item)"
              >
                <div class="mover-item">{{ item.id }}
                  <div
                    v-for="(siteItem,Ikey) of item.site"
                    :key="siteItem.id"
                    class="mover-item-site"
                    :style="`left: ${siteItem.left}%;`"
                    @click.stop="siteBlock(row.fid,siteItem.id, key, Ikey, siteItem)"
                  >
                    <!-- 站点 -->
                    <el-popover v-model="siteItem.changeSiteShow" placement="right" trigger="manual" :visible-arrow="false">
                      <div style="text-align: center;">
                        <div style="margin: 15px 0;" />
                        <div>
                          <el-button-group>
                            <el-button size="mini" type="primary" @click="btns('ok',row.fid, key, item, row.items)">确定</el-button>
                            <el-button size="mini" type="primary" @click="siteItem.changeSiteShow = false">取消</el-button>
                          </el-button-group>
                        </div>
                      </div>
                      <div slot="reference" class="timeHover" />
                    </el-popover>
                  </div>

                </div>
                <!-- 点击时间调整 -->
                <el-popover v-model="item.changeTimeShow" placement="right" trigger="manual" :visible-arrow="false">
                  <div style="text-align: center;">
                    <div style="margin: 15px 0;">
                      <el-time-select
                        v-model="item.startTime"
                        placeholder="起始时间"
                        :picker-options="{
                          start: '00:00',
                          step: '00:01',
                          end: '23:59',
                        }"
                      />
                    </div>
                    <div>
                      <el-button-group>
                        <el-button size="mini" type="primary" @click="btns('ok',row.fid, key, item, row.items)">确定</el-button>
                        <el-button size="mini" type="primary" @click="item.changeTimeShow = false">取消</el-button>
                      </el-button-group>
                    </div>
                  </div>
                  <div slot="reference" class="timeHover" />
                </el-popover>
              </div>
            </draggable>
          </div>
        </div>
      </div>
    </draggable>
    <div style="margin-top: 30px;">{{ schedulesList }}</div>
    <el-dialog
      title="提示"
      :visible.sync="dialogVisible"
      width="30%"
      :modal="false"
    >
      <span>这是一段信息</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
      </span>
    </el-dialog>

  </div>
</template>
<script>
import draggable from 'vuedraggable'
import BigNumber from 'bignumber.js'
export default {
  name: 'TwoLists',
  components: {
    draggable
  },
  data() {
    return {
      startTime: '20:00',
      endTime: '04:00',
      // 排期
      schedulesList: [],
      // 时间刻度
      timeList: [],
      // 总分钟
      totalMin: 0,
      // 每分钟
      perMin: 0,
      timeIntervalOptions: [{
        value: 60,
        label: '小时'
      }, {
        value: 30,
        label: '半小时'
      }, {
        value: 15,
        label: '15分钟'
      }],
      timeInterval: 60,
      // 是否是选中的时间子块
      loop: null,
      // 存根数据
      stubData: {},
      stubSiteData: {},
      // 时间间隔颜色
      itemBGcolor: ['#DAA520', '#B22222'],

      dialogVisible: false,
      itemTime: {
        startTime: '',
        endTime: ''
      }
    }
  },
  created() {
    this.getData()
  },
  methods: {
    getData() {
      this.schedulesList = [
        {
          fid: 0,
          items: [
            { id: '001',
              startTime: '20:30',
              endTime: '21:50',
              changeTimeShow: false,
              site: [
                {
                  id: '2357',
                  disMin: '20'
                },
                {
                  id: '2358',
                  disMin: '60'
                }
              ]
            }

          ]
        },
        {
          fid: 1,
          items: [
            { id: '002',
              startTime: '21:00',
              endTime: '22:45',
              site: [
                {
                  id: '2327',
                  disMin: '10'
                },
                {
                  id: '2328',
                  disMin: '30'
                }
              ]
            },
            { id: '003',
              startTime: '00:20',
              endTime: '01:58',
              site: [
                {
                  id: '2337',
                  disMin: '20'
                }
              ]
            }
          ]
        },
        {
          fid: 3,
          items: [
            { id: '004',
              startTime: '22:30',
              endTime: '03:05',
              site: [
                {
                  id: '2347',
                  disMin: '100'
                },
                {
                  id: '2348',
                  disMin: '160'
                }
              ]
            }

          ]
        }
      ]
      this.changeEndTime()
      this.initData()
    },
    // 初始数据过滤
    async initData() {
      this.schedulesList.forEach((group) => {
        group.items.forEach((item) => {
          // item.changeTimeShow = false
          const TimeC = this.getTimeCompareH(item.startTime, item.endTime)
          let startTime1 = ''
          let endTime1 = ''
          // 判断说选时间是否跨天
          if (TimeC) {
            startTime1 = '2023-10-23T' + item.startTime
            endTime1 = '2023-10-24T' + item.endTime
          } else {
            startTime1 = '2023-10-23T' + item.startTime
            endTime1 = '2023-10-23T' + item.endTime
          }
          item.itemTotalMin = this.getMinBetweenY(startTime1, endTime1)
          const itemTotalMin = new BigNumber(this.getMinBetweenY(startTime1, endTime1))
          const perMin1 = new BigNumber(this.perMin)
          item.width = `${itemTotalMin.times(perMin1).dp(4).toNumber()}`
          const TimeW = this.getTimeCompareH(this.startTime, item.startTime)
          let startTime2 = ''
          let endTime2 = ''
          // 判断说选时间是否跨天
          if (TimeW) {
            startTime2 = '2023-10-23T' + this.startTime
            endTime2 = '2023-10-24T' + item.startTime
          } else {
            startTime2 = '2023-10-23T' + this.startTime
            endTime2 = '2023-10-23T' + item.startTime
          }
          const itemLeftMin = new BigNumber(this.getMinBetweenY(startTime2, endTime2))
          item.left = `${itemLeftMin.times(perMin1).dp(4).toNumber()}`
          item.site.forEach((siteItem) => {
            const itemTotalWidth = new BigNumber(100)
            const disMin = new BigNumber(siteItem.disMin)
            siteItem.left = `${itemTotalWidth.div(itemTotalMin).times(disMin).dp(4).toNumber()}`
          })
        })
      })
    },
    // 时间选择时间区间选择
    changeEndTime() {
      console.log(this.startTime, this.endTime)
      const TimeC = this.getTimeCompareH(this.startTime, this.endTime)
      let startTime1 = ''
      let endTime1 = ''
      // 判断说选时间是否跨天
      if (TimeC) {
        startTime1 = '2023-10-23T' + this.startTime
        endTime1 = '2023-10-24T' + this.endTime
      } else {
        startTime1 = '2023-10-23T' + this.startTime
        endTime1 = '2023-10-23T' + this.endTime
      }
      this.totalMin = this.getMinBetweenY(startTime1, endTime1)
      this.timeList = this.generateTimeArray(startTime1, endTime1, this.timeInterval)
      const totalWidth = new BigNumber(100)
      const totalMin = new BigNumber(this.totalMin)
      this.perMin = totalWidth.div(totalMin).dp(4).toNumber()
    },
    start(e, val) {
      console.log(e, 'start', val)
      this.baseRows = []
      this.baseRows = JSON.parse(JSON.stringify(val))
    },
    end(val) {
      const aa = this.checkTimeOverlap(this.schedulesList)
      if (aa) {
        this.schedulesList = this.schedulesList.filter(row => row.items.length > 0)
      } else {
        console.log('时间冲突')
        this.schedulesList = this.baseRows
      }
      console.log(this.schedulesList, aa, val)
    },
    // 子块节点的单击
    timeItemBlock(code, key, item) {
      this.stubData = JSON.parse(JSON.stringify(item))
      // 找到对应的节点，根据条件把对应节点打开或者关闭，但是其它节点要全部关闭
      this.schedulesList.map((v, i) => {
        v.items.map((val, j) => {
          if (v.fid === code && j === key) {
            console.log(item.changeTimeShow)
            item.changeTimeShow = !item.changeTimeShow
            // this.itemStart = item.startTime
            // this.itemEnd = item.endTime
          } else {
            this.schedulesList[i].items[j].changeTimeShow = false
          }
        })
      })
      // return false
    },
    // 点击时间调整-按钮组
    btns(type, code, key, item, row) {
      if (type === 'cancel') {
        item.changeTimeShow = false
      } else if (type === 'ok') {
        console.log(row, '@@@row', item)
        item.endTime = this.calculateEndTime(item.startTime, item.itemTotalMin)
        const hasOverlap = this.checkTimeOverlapL(row)
        console.log('hasOverlap', hasOverlap)
        if (!hasOverlap) {
          item.startTime = this.stubData.startTime
          console.log('时间区间有重叠，报错##')
          return
        } else {
          // 注:用改过的时间无法和原时间判断是否跨天， 判断开始时间睡小用谁，结束时间谁大用谁
          console.log('时间区间无重叠@@')
          this.initData()
        }
        item.changeTimeShow = false
      }
    },
    // 站点单点击
    siteBlock(rowId, itemId, key, Ikey, item) {
      console.log('zhandian', rowId, itemId, key, Ikey, item)
      this.stubSiteData = JSON.parse(JSON.stringify(item))
      // 找到对应的节点，根据条件把对应节点打开或者关闭，但是其它节点要全部关闭
      // 自己设定开始时间不存在跨天存在
      this.schedulesList.map((v, i) => {
        v.items.map((val, j) => {
          if (v.fid === rowId && j === key) {
            val.site.map((s, l) => {
              if (s.id === itemId) {
                console.log(s, '@@@@')
                item.changeSiteShow = !item.changeSiteShow
              } else {
                this.schedulesList[i].items[j].site[l].changeSiteShow = false
              }
            })
          }
        })
      })
    },
    // 开始时间比较结束时间(YYYY-MM-DD HH:mm)
    getTimeCompareY(startTime, endTime) {
      const startDate = new Date(startTime)
      const endDate = new Date(endTime)
      const isCrossDay = startDate.getDate() !== endDate.getDate()
      if (isCrossDay) {
        console.log('开始时间和结束时间跨天')
      } else {
        console.log('开始时间和结束时间不跨天')
      }
      return isCrossDay
    },
    // 时间比较(HH:mm)
    getTimeCompareH(startTime, endTime) {
      const [startHour, startMinute] = startTime.split(':')
      const [endHour, endMinute] = endTime.split(':')
      const startMinutes = parseInt(startHour) * 60 + parseInt(startMinute)
      const endMinutes = parseInt(endHour) * 60 + parseInt(endMinute)
      const isCrossDay = startMinutes > endMinutes
      if (isCrossDay) {
        console.log('开始时间和结束时间跨天True')
      } else {
        console.log('开始时间和结束时间不跨天false')
      }
      return isCrossDay
    },
    // 时间间隔分钟计算
    getMinBetweenY(startTime, endTime) {
      // const startTime = '2023-10-21 08:00'
      // const endTime = '2023-10-21 22:00'
      const startDate = new Date(startTime)
      const endDate = new Date(endTime)
      const milliseconds = endDate - startDate
      const minutes = Math.floor(milliseconds / (1000 * 60))
      console.log('时间间隔为：', minutes, '分钟')
      return minutes
    },
    // 跨一天时间生成数组
    generateTimeArray(startTime, endTime, intervalMinutes) {
      // const startDate = new Date('2000-01-01T' + startTime);
      // const endDate = new Date('2000-01-02T' + endTime);
      const startDate = new Date(startTime)
      const endDate = new Date(endTime) // endDate 比 startDate 多了一天
      const intervalMilliseconds = intervalMinutes * 60000
      const result = []
      let currentTime = startDate
      while (currentTime <= endDate) {
        const currentHour = currentTime.getHours().toString().padStart(2, '0')
        const currentMinute = currentTime.getMinutes().toString().padStart(2, '0')
        result.push(currentHour + ':' + currentMinute)
        currentTime = new Date(currentTime.getTime() + intervalMilliseconds)
      }
      return result
    },
    // 判断时间区间是否重合1
    timeToMinutes(time) {
      const [hour, minute] = time.split(':').map(Number)
      return hour * 60 + minute
    },
    // 判断时间区间是否重合2
    isTimeOverlap(startTime1, endTime1, startTime2, endTime2) {
      const startMinutes1 = this.timeToMinutes(startTime1)
      const endMinutes1 = this.timeToMinutes(endTime1)
      const startMinutes2 = this.timeToMinutes(startTime2)
      const endMinutes2 = this.timeToMinutes(endTime2)

      // 情况一：两个时间区间都在同一天内
      if (startMinutes1 <= endMinutes1 && startMinutes2 <= endMinutes2) {
        return startMinutes1 <= endMinutes2 && startMinutes2 <= endMinutes1
      }

      // 情况二：第一个时间区间跨越了 0 点
      if (startMinutes1 > endMinutes1 && startMinutes2 < endMinutes2) {
        return startMinutes1 <= endMinutes2 + 24 * 60 && startMinutes2 >= startMinutes1 - 24 * 60
      }

      // 情况三：第二个时间区间跨越了 0 点
      if (startMinutes1 < endMinutes1 && startMinutes2 > endMinutes2) {
        return startMinutes2 <= endMinutes1 + 24 * 60 && startMinutes1 >= startMinutes2 - 24 * 60
      }

      // 情况四：两个时间区间都跨越了 0 点
      return (
        (startMinutes1 <= startMinutes2 && startMinutes2 <= endMinutes1) ||
    (startMinutes1 <= endMinutes2 && endMinutes2 <= endMinutes1) ||
    (startMinutes2 <= startMinutes1 && startMinutes1 <= endMinutes2) ||
    (startMinutes2 <= endMinutes1 && endMinutes1 <= endMinutes2)
      )
    },
    // 判断时间区间是否重合3(总)
    checkTimeOverlap(data) {
      for (let i = 0; i < data.length; i++) {
        const items = data[i].items
        for (let j = 0; j < items.length - 1; j++) {
          const item1 = items[j]
          const startTime1 = item1.startTime
          const endTime1 = item1.endTime

          for (let k = j + 1; k < items.length; k++) {
            const item2 = items[k]
            const startTime2 = item2.startTime
            const endTime2 = item2.endTime

            if (this.isTimeOverlap(startTime1, endTime1, startTime2, endTime2)) {
              console.log(`fid ${i}, items ${j} 和 items ${k} 的时间区间重合`)
              return false
            }
          }
        }
      }
      return true
    },
    // 判断时间区间是否重合3(分)
    checkTimeOverlapL(items) {
      for (let j = 0; j < items.length - 1; j++) {
        const item1 = items[j]
        const startTime1 = item1.startTime
        const endTime1 = item1.endTime

        for (let k = j + 1; k < items.length; k++) {
          const item2 = items[k]
          const startTime2 = item2.startTime
          const endTime2 = item2.endTime

          if (this.isTimeOverlap(startTime1, endTime1, startTime2, endTime2)) {
            console.log(`items ${j} 和 items ${k} 的时间区间重合`)
            return false
          }
        }
      }
      return true
    },
    // 计算结束时间
    calculateEndTime(startTime, duration) {
      const [startHour, startMinute] = startTime.split(':').map(Number) // 将起始时间转换为小时和分钟
      const totalMinutes = startHour * 60 + startMinute // 起始时间转换为分钟数
      const endMinutes = totalMinutes + duration // 结束时间的分钟数
      let endHour
      if (endMinutes >= 1440) {
        // 如果结束分钟数超过了 1440（即 24 小时），说明结束时间是第二天
        endHour = Math.floor((endMinutes - 1440) / 60)
      } else {
        endHour = Math.floor(endMinutes / 60) // 计算小时部分
      }
      const endMinute = endMinutes % 60 // 计算分钟部分

      // 格式化结束时间为 "HH:MM" 的字符串
      const endTime = `${String(endHour).padStart(2, '0')}:${String(endMinute).padStart(2, '0')}`

      return endTime
    }
    //     function addOneDay(dateString) {
    //   // 将日期字符串转换为 Date 对象
    //   let date = new Date(dateString);

    //   // 获取当前日期的日
    //   let day = date.getDate();

    //   // 将日期设置为下一天
    //   date.setDate(day + 1);

    //   // 获取新的日期的年、月、日
    //   let year = date.getFullYear();
    //   let month = date.getMonth() + 1; // 注意月份从0开始，需要加1
    //   let newDay = date.getDate();

    //   // 格式化为指定格式的字符串（例如：yyyy-mm-dd）
    //   let formattedDate = `${year}-${month.toString().padStart(2, '0')}-${newDay.toString().padStart(2, '0')}`;

    //   return formattedDate;
    // }

    // let originalDate = "2023-05-23";
    // let newDate = addOneDay(originalDate);
    // console.log(newDate);

  }
}
</script>
<style scoped lang="scss">
.sortable{
  // width: 810px;
  width: 100%;
  display: flex;
  align-items: end;
  background: red;
  margin-bottom: 8px;
  padding: 5px;
}
.sortable-list{
  height: 100%;
  background: grey;
  padding: 5px 15px;
}
.row-item{
  display: flex;
  -webkit-box-align: center;
  -ms-flex-align: center;
  align-items: center;
  box-flex: 1
}
// 刻度
.slide-ruler {
  position: relative;
  left: 0px;
  // width: 730px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-left:28px ;
  padding-right: 20px;
}
.slide-ruler-item {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  left: 0px;
  // width: 730px;
  width: 100%;
  display: flex;
  justify-content: space-between;
  align-items: center;
  z-index: 99;
}
.scale {
  text-align: center;
  width: 15px;
  font-size: 12px;
}
.scale-item {
  text-align: center;
  width: 2px;
  height: 18px;
  border-radius: 9px;
  background: #008B8B;
}
.slide-list {
  // width: 720px;
  position: relative;
  width: 100%;
}
.slide-box {
  width: 100%;
  height: 20px;
  background: 	#483D8B;
  display: flex;
  position: relative;
}
.slide-box-item {
  height: 100%;
  position: absolute;
  z-index: 999;
  padding: 0 5px;
  box-sizing: border-box;
  cursor: pointer;
}
.mover-item{
  display: inline-block;
  width: 100%;
  height: 20px;
  position: relative;
  display: flex;
  align-items: center;
}
.mover-item-site{
  position: absolute;
  width: 10px;
  height: 10px;
  background: green;
}
.i-class{
  width: 20px;
  height: 20px;
  position: absolute;
  display: inline-block;
  background: greenyellow;
  background-position: -5px;
  z-index: 1;
}
.i-left-class{
  left: -3px;
}
.i-right-class{
  right: -3px;
}
.i-class:hover{
  cursor:w-resize
}
.timeHover {
  width: 100%;
  height: 100%;
  display: inline-block;
}

</style>
